/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Javabeans;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

/**
 *
 * @author Tariq
 */
public class Customer implements Comparable{
    private static Customer neighbour;
    private Double distanceFromNeighbour=-1.0;

    private static  ArrayList<String> attributeNames;
    private ArrayList<Double> attributeValues;
    private static HashMap<Integer, Double[]> attributeStats = new HashMap<Integer, Double[]>();
    
    private static int outputIndex;
    private static String outputName;
    private String outputValue;

    public Customer(String[] values){
        attributeValues = new ArrayList<Double>();
        addAttributes(values);
    }
    public double getDistanceFromNeighbour(){
        return distanceFromNeighbour;
    }
    public static void setNeighbour(Customer n){
        neighbour = n;
    }

    public static String[]  getAttributeNames(){
        return Customer.attributeNames.toArray(new String[0]);
    }
    public static void  setAttributeNames(String[] names, int outputIndex){
        attributeNames = new ArrayList<String>();
        Customer.outputIndex = outputIndex;
        for(int i = 0; i<names.length;i++){
            if(i!=outputIndex){
                attributeNames.add(names[i]);
            }else{
                outputName=names[i];
            }
        }
    }
    public Double[] getAttributeValues(){
        return this.attributeValues.toArray(new Double[0]);
    }

    public void addAttributes (String[] values){
        for(int i = 0; i<values.length;i++){
            if(i!=outputIndex){
                attributeValues.add(Double.valueOf(values[i]));
            }else{
                this.outputValue=values[i];
            }
        }
    }

    public void setAttribute(int index, double value){
        attributeValues.set(index, value);
    }
    public static HashMap<Integer, Double[]> getAttributeStats(){
        return Customer.attributeStats;
    }
    public static Double[] getAttributeStats(int index){
        return Customer.attributeStats.get(index);
    }
    public static void setAttributeStats(int index, Double[] values){
        attributeStats.put(index,values);
    }


    public static Customer convertToCustomer (String[] values){
        Customer customer = new Customer(values);
        return customer;
    }
    public void calculateDistanceFromNeighbour(){
        distanceFromNeighbour=distance(neighbour);
    }
    public String getOutputValue(){
        return this.outputValue;
    }
    public void setOutputValue(String outputValue){
        this.outputValue = outputValue;
    }
    public Double  distance (Customer oldCustomer){
        ArrayList<Double> a = oldCustomer.attributeValues;
        ArrayList<Double> b = this.attributeValues;

        int count=0;
        if(a.size()==b.size()){
            count = a.size();
        }else{
            return null;
        }

        double distance=0.0;
        for(int i=0;i<count;i++){
            distance+=Math.pow(
                normalizeAttribute(i,a.get(i))-normalizeAttribute(i,b.get(i))
                ,2);
            //System.out.print("("+normalizeAttribute(i,a.get(i))+"-"+normalizeAttribute(i,b.get(i))+")=");
            //System.out.print(normalizeAttribute(i,a.get(i))-normalizeAttribute(i,b.get(i))+"\n");
        }
        //System.out.println("distance: "+distance);
        distance = Math.sqrt(distance);
        return distance;
    }
    public String toString(){
        String row="";
        Iterator it = attributeValues.iterator();
        while(it.hasNext()){
            row += (Double)it.next()+", ";
        }
        row +=outputValue;
        return row;
    }
    public int compareTo(Object o) {
        Customer otherCustomer = (Customer)o;
        return this.distanceFromNeighbour.compareTo(otherCustomer.getDistanceFromNeighbour());
    }
    private double normalizeAttribute(int attIndex,double value){
        Double[] stats = Customer.attributeStats.get(attIndex);
        double max = stats[0];
        double min = stats[1];
        return (value-min)/(max-min);
    }
    public boolean isSameOutput(Customer other){
        return this.outputValue==other.outputValue;
    }
}
